package us.gaaoc.framework.webapp.controllers;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.faces.component.UIParameter;
import javax.faces.model.SelectItem;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import us.gaaoc.framework.model.Court;
import us.gaaoc.framework.model.LegalPreparer;
import us.gaaoc.framework.model.Person;
import us.gaaoc.framework.model.constants.Constants;

/**
 * This is the controller for the filings single table view.
 * 
 * The controller is configured with two main parameters.
 * 
 * 1) tableList This setting tells us what sub-tables of the hibernateView table
 * we want the user to see. This property is a List<TableView>. This setting
 * controls what different categories the user can see.
 * 
 * The default tableView takes seven arguments 1) the ID 2) the visible
 * description 3) statusCode1 - a status code to show
 * 
 * The table list must have two TableViews with specific ID's: rejected - Cases
 * rejected by the next person or entity in the chain. default - the default
 * table to show.
 * 
 * 
 * Faces configuration:
 * 
 * <pre>
 * 	<managed-bean>
 * 		<managed-bean-name>nameOfBean</managed-bean-name>
 * 		<managed-bean-class>
 * 			us.gaaoc.framework.webapp.controllers.AttorneyFilingsTableController
 * 		</managed-bean-class>
 * 		<managed-bean-scope>request</managed-bean-scope>
 * 		<managed-property>			
 *   			<property-name>tableList</property-name>
 *   			<value>#{el-expression-of-bean}</value>  			
 * 		</managed-property> 
 * 	</managed-bean>
 * </pre>
 * 
 * @author artripa
 */
public class AttorneyFilingsTableController extends BaseTableController {

	private static final long serialVersionUID = 1L;
	private UIParameter caseDetailsPageClicked;

	/*
	 * (non-Javadoc)
	 * 
	 * @see us.gaaoc.framework.webapp.controllers.BaseTableController#getRole()
	 */
	@Override
	public int getRole() {
		return 4; // attorney
	}

	/* Getters */
	public int getRejectedCount() throws HibernateException,
			ClassNotFoundException {
		return this.getDataSize(this.findtable("rejectedStatusTable"));
	}

	@Override
	public void additionalQuery(List<String> joins, List<String> predicates,
			Map<String, Object> additionalParams) {
		{// agent filtering
			if (getAgentUuid().equalsIgnoreCase(""))
				return; // no agent filtering

			joins.add("personParticipants ppAgent");
			predicates.add("ppAgent.caseRecordUuid = cr.uuid");
			predicates.add("ppAgent.relationshipCode = :agentRole");
			predicates.add("ppAgent.personUuid = :agentUuid");

			additionalParams.put("agentUuid", getAgentUuid());
			additionalParams.put("agentRole",
					Constants.ParticipantRelationship.Filer);
		}
	}

	public List<SelectItem> getAgents() {
		Person p = this.getPerson();
		Court c = this.getModelFacade().findCourt(this.getCourtUuid());

		List<SelectItem> agents = new ArrayList<SelectItem>();
		for (LegalPreparer lp : this.getAgentsSendingToAttorney(p, c)) {
			agents.add(new SelectItem(lp.getPerson().getUuid(), lp.getPerson()
					.getFirstName() + " " + lp.getPerson().getLastName()));
		}
		return agents;
	}

	protected List<LegalPreparer> getAgentsSendingToAttorney(Person attorney,
			Court court) {
		Session s = this.getModelFacade().getSession();

		return s.createSQLQuery(
				"SELECT lp.* "
						+ "FROM legalPreparer lp, person p, attorney a, personOrganizations po "
						+ "WHERE p.uuid = :personUuid "
						+ "AND a.personUuid = p.uuid "
						+ "AND lp.attorneyUuid = a.uuid "
						+ "AND po.personUuid = a.personUuid "
						+ "AND a.organizationUuid = po.organizationUuid "
						+ "AND lp.orgUuid = po.organizationUuid "
						+ "AND po.courtUuid = :courtUuid ")
				.addEntity("lp", LegalPreparer.class)
				.setParameter("personUuid", attorney.getUuid())
				.setParameter("courtUuid", court.getUuid()).list();

		//
		// return
		// s.createQuery("select lp from LegalPreparer lp join lp.person.organizations o where o.court = :court and lp.attorney.person = :attorney")
		// .setParameter("court",court)
		// .setParameter("attorney",attorney)
		// .list();
	}

	/* Navigation */

	/**
	 * Navigates the user to the case details page.
	 * 
	 * @requestparam caseUuid the UUID of the case.
	 */

	@SuppressWarnings("unchecked")
	public String gotoCaseDetailsPage() {
		Map<String, String> sessionMap = this.getSessionMap();
		Map requestMap = this.getFacesContext().getExternalContext()
				.getRequestParameterMap();
		String caseUuid = ((String) requestMap.get("caseUuid"));
		sessionMap.put("caseUuid", caseUuid);
		sessionMap.put("from", "allFilingsTablesPage");

		return "gotoCaseDetailsPage";
	}

	public void clearCase(String caseUuid ) {
		Map requestMap = this.getFacesContext().getExternalContext()
				.getRequestParameterMap();	
		this.getModelFacade().updateCaseRecordForClearCase(caseUuid, true,
				this.getCourtUuid());		
	}

	/**
	 * Navigates the user to the trash can page.
	 */
	public String gotoTrashCanPage() {
		return "trashcanPage";
	}

	/**
	 * Navigates the user to the existing filing page.
	 */
	public String gotoExistingFilingPage() {
		return "existingFilingPage";
	}

	/**
	 * Navigates the user to the search page. Also, saves the current page to
	 * the session map.
	 */
	@SuppressWarnings("unchecked")
	public String gotoSearchPage() {
		Map<String, String> sessionMap = this.getSessionMap();
		sessionMap.put("from", "attFilingsTablesPage");
		return "gotoSearchPage";
	}

	/**
	 * In the future, this page will navigate the user to the reports page.
	 * Currently, the method simply returns the user to the current page.
	 */
	@SuppressWarnings("unchecked")
	public String gotoReportsPage() {
		Map<String, String> sessionMap = this.getSessionMap();
		sessionMap.put("from", "attFilingsTablesPage");
		return "gotoReportsPage";
	}

	/**
	 * Navigates the user to the new filings page. Also, saves the current page
	 * to the session map.
	 */
	@SuppressWarnings("unchecked")
	public String createNewFiling() {
		Map<String, String> sessionMap = this.getSessionMap();
		sessionMap.put("from", "allFilingsPage");
		sessionMap.remove("caseUuid"); // fix for issue GAJETWOX-124
		return "createNewFilingPage";
	}

	/**
	 * Navigates to the history of the case
	 * 
	 * @requestparam caseUuid the UUID of the case record
	 */
	@SuppressWarnings("unchecked")
	public String gotoHistoryPage() {
		Map<String, String> sessionMap = this.getSessionMap();
		Map requestMap = this.getFacesContext().getExternalContext()
				.getRequestParameterMap();
		String caseUuid = ((String) requestMap.get("caseUuid"));
		sessionMap.put("caseUuid", caseUuid);
		sessionMap.put("from", "allFilingsTablePage");
		return "gotoCaseHistoryPage";
	}

	public void setCaseDetailsPageClicked(UIParameter caseDetailsPageClicked) {
		this.caseDetailsPageClicked = caseDetailsPageClicked;
	}

	public UIParameter getCaseDetailsPageClicked() {
		return caseDetailsPageClicked;
	}

	public String getAgentUuid() {
		if(this.getSessionMap().containsKey("attorney.filterByAgent"))				
			return (String) this.getSessionMap().get("attorney.filterByAgent");
		else
			return "";
	}

	public void setAgentUuid(String agentUuid) {
		this.getSessionMap().put("attorney.filterByAgent", agentUuid);
	}

}
